<?php

namespace App\Services\Ocean;

use App\Common\Helpers\Functions;
use App\Common\Tools\CustomException;
use App\Enums\Ocean\OceanProjectStatusEnum;
use App\Models\Ocean\OceanProjectModel;

class OceanProjectService extends OceanService
{
    /**
     * constructor.
     * @param string $appId
     */
    public function __construct($appId = ''){
        parent::__construct($appId);
    }

    /**
     * @param $accountIds
     * @param $accessToken
     * @param $filtering
     * @param $page
     * @param $pageSize
     * @param array $param
     * @return mixed|void
     * sdk并发获取列表
     */
    public function sdkMultiGetList($accountIds, $accessToken, $filtering, $page, $pageSize, $param = []){
        // 延迟
        usleep(500000);
        return $this->sdk->multiGetProjectList($accountIds, $accessToken, $filtering, $page, $pageSize, $param);
    }

    /**
     * @param array $option
     * @return bool
     * @throws CustomException
     * 同步
     */
    public function sync($option = []){
        ini_set('memory_limit', '2048M');

        $t = microtime(1);

        $accountIds = [];
        // 账户id过滤
        if(!empty($option['account_ids'])){
            $accountIds = $option['account_ids'];
        }

        // 并发分片大小
        if(!empty($option['multi_chunk_size'])){
            $multiChunkSize = min(intval($option['multi_chunk_size']), 8);
            $this->sdk->setMultiChunkSize($multiChunkSize);
        }

        $filtering = [];

        // 创建日期
        if(!empty($option['create_date'])){
            $filtering['project_create_time'] = Functions::getDate($option['create_date']);
        }

        // 更新日期
        if(!empty($option['update_date'])){
            $filtering['project_modify_time'] = Functions::getDate($option['update_date']);
        }

        // 状态
        if(!empty($option['status'])){
            $status = strtoupper($option['status']);
            Functions::hasEnum(OceanProjectStatusEnum::class, $status);
            $filtering['status'] = $status;
        }else{
            $filtering['status'] = OceanProjectStatusEnum::PROJECT_STATUS_ALL;
        }

        // id
        if(!empty($option['ids'])){
            $filtering['ids'] = $option['ids'];
        }

        // 公司
        $companys = [];
        if(!empty($option['companys'])){
            $companys = $option['companys'];
        }

        // 修复历史
        if(!empty($option['fix_history'])){
            $fixHistory = explode(",", $option['fix_history']);
            if(is_array($fixHistory) && count($fixHistory) == 2){
                Functions::consoleDump("fix history: {$fixHistory[0]} - $fixHistory[1]");
                $sql = "
                    SELECT account_id FROM ocean_promotion_reports
                    WHERE stat_datetime BETWEEN '{$fixHistory[0]}' AND '$fixHistory[1]'
                    AND stat_cost > 0
                    AND project_id NOT IN (
                        SELECT project_id FROM channel_project_logs
                    )
                    GROUP BY account_id
                ";
                $fixItems = $this->execSql($sql);
                //Functions::consoleDump($fixItems);
                $actIds = ['xxx'];
                foreach($fixItems as $fixItem){
                    $actIds[] = $fixItem['account_id'];
                }
                $accountIds = array_merge($accountIds, $actIds);
            }
        }

        // 获取子账户组
        $accountGroup = $this->getSubAccountGroup($accountIds, $companys);

        $datetime = date('Y-m-d H:i:s', TIMESTAMP);

        $pageSize = 100;
        foreach($accountGroup as $g){
            $items = $this->multiGetPageList($g, $filtering, $pageSize);
            Functions::consoleDump('count:'. count($items));

            $data = [];
            // 保存
            foreach($items as $item) {
                $item['extends'] = $item;
                $item['id'] = $item['project_id'];
                $item['name'] = $item['name'] ?? '';
                $item['budget'] = $item['delivery_setting']['budget'] ?? 0;
                $item['cpa_bid'] = $item['delivery_setting']['cpa_bid'] ?? 0;
                $item['deep_cpabid'] = $item['delivery_setting']['deep_cpabid'] ?? 0;
                $item['budget_mode'] = $item['delivery_setting']['budget_mode'] ?? '';
                $item['landing_type'] = $item['landing_type'] ?? '';
                $item['app_promotion_type'] = $item['app_promotion_type'] ?? '';
                $item['marketing_goal'] = $item['marketing_goal'] ?? '';
                $item['ad_type'] = $item['ad_type'] ?? '';
                unset($item['extends']['keywords']);

                // 单位:分
                $item['budget'] *= 100;
                $item['cpa_bid'] *= 100;
                $item['deep_cpabid'] *= 100;

                $item['created_at'] = $datetime;
                $item['updated_at'] = $datetime;
                $item['extends'] = json_encode($item['extends']);

                //$this->save($item);
                $data[] = $item;
            }

            $this->batchSave($data);
        }

        $t = microtime(1) - $t;
        Functions::consoleDump($t);

        return true;
    }

    /**
     * @param $data
     * @return array
     * 批量保存
     */
    public function batchSave($data){
        $oceanProjectModel = new OceanProjectModel();
        $ret = $oceanProjectModel->chunkInsertOrUpdate($data, 100, $oceanProjectModel->getTable(), $oceanProjectModel->getTableColumnsWithPrimaryKey());
        return $ret;
    }

    /**
     * @param $item
     * @return mixed
     * @throws CustomException
     * 保存
     */
    public function save($item){
        $where = ['id', '=', $item['id']];
        $ret = Functions::saveChange(OceanProjectModel::class, $where, $item);
        return $ret;
    }
}
